#include <libayatana-appindicator/app-indicator.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/wait.h>
#include <signal.h>
#include <gdk/gdkkeysyms.h>
#include <fcntl.h>

// -------------------------- 全局定义 --------------------------
typedef struct {
    char file_path[1024];
    char url[1024];
    char geometry[32];
    bool keep_cache;
} Config;

typedef struct {
    char* history[30];
    int idx;
    int count;
} InputHistory;

// 全局变量：新增下载状态相关
static Config cfg;
static GtkWidget *main_window, *help_window;
static GtkWidget *entry_file, *entry_url, *entry_geo;
static GtkWidget *btn_browse, *btn_play, *btn_stop, *btn_clean, *btn_help;
static GtkWidget *chk_keep_cache, *lbl_error, *progress_bar, *lbl_progress;
static InputHistory hist_file, hist_url, hist_geo;
static AppIndicator *tray_indicator;
static pid_t play_pid = -1;
static pid_t play_pgid = -1;
static int progress_pipe[2] = {-1, -1};  // 下载进度通信管道
static const char* help_text = 
    "Usage:\n"
    "  - Select local file or enter URL (choose one)\n"
    "  - Window geometry: widthxheight+X+Y (default 1920x1080+0+0)\n"
    "  - Keep Cache: Reuse cache for same URL\n"
    "  - Clean cache: Delete all cached files\n"
    "  - Press ESC to close help\n"
    "  - Ctrl+C/V/X/A/Z: Copy/Paste/Cut/SelectAll/Undo";

// -------------------------- 提前声明回调函数 --------------------------
static gboolean on_help_key_press(GtkWidget* w, GdkEventKey* ev, gpointer d);
static void on_help_destroy(GtkWidget* w, gpointer d);
static void on_stop_clicked(GtkWidget* w, gpointer d);
static gboolean on_progress_pipe_read(GIOChannel* channel, GIOCondition cond, gpointer data);
static void set_download_progress(int progress);

// -------------------------- 工具函数 --------------------------
static void input_history_init(InputHistory* hist) {
    memset(hist->history, 0, sizeof(hist->history));
    hist->idx = 0;
    hist->count = 0;
}

static void input_history_save(InputHistory* hist, const char* text) {
    if (hist->count >= 30) {
        free(hist->history[0]);
        for (int i = 0; i < 29; i++) hist->history[i] = hist->history[i+1];
        hist->count--;
        hist->idx--;
    }
    hist->history[hist->count] = strdup(text);
    hist->count++;
    hist->idx = hist->count;
}

static void input_history_undo(InputHistory* hist, GtkWidget* entry) {
    if (hist->idx <= 0) return;
    hist->idx--;
    gtk_entry_set_text(GTK_ENTRY(entry), hist->history[hist->idx]);
}

static void set_error(const char* msg) {
    gtk_label_set_text(GTK_LABEL(lbl_error), msg);
    gtk_widget_show(lbl_error);
    g_timeout_add_seconds(3, (GSourceFunc)gtk_widget_hide, lbl_error);
}

// 设置管道为非阻塞模式
static void set_pipe_nonblock(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

// 更新下载进度UI
static void set_download_progress(int progress) {
    if (progress < 0) {
        // 无下载：隐藏进度条和标签
        gtk_widget_hide(progress_bar);
        gtk_widget_hide(lbl_progress);
        return;
    }

    // 显示进度组件
    gtk_widget_show(progress_bar);
    gtk_widget_show(lbl_progress);

    if (progress == 101) {
        // 下载完成
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), 1.0);
        gtk_label_set_text(GTK_LABEL(lbl_progress), "Download completed!");
        // 3秒后重置
        g_timeout_add_seconds(3, (GSourceFunc)set_download_progress, GINT_TO_POINTER(-1));
    } else {
        // 下载中：更新进度条和百分比
        gdouble frac = (gdouble)progress / 100.0;
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), frac);
        char buf[32];
        snprintf(buf, sizeof(buf), "Download: %d%%", progress);
        gtk_label_set_text(GTK_LABEL(lbl_progress), buf);
    }
}

// -------------------------- 业务逻辑函数 --------------------------
static void open_file_dialog(GtkWidget* widget, gpointer data) {
    GtkWidget* dialog = gtk_file_chooser_dialog_new(
        "Select Video File",
        GTK_WINDOW(main_window),
        GTK_FILE_CHOOSER_ACTION_OPEN,
        "Cancel", GTK_RESPONSE_CANCEL,
        "Open", GTK_RESPONSE_ACCEPT,
        NULL
    );

    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        gtk_entry_set_text(GTK_ENTRY(entry_file), path);
        input_history_save(&hist_file, path);
        g_free(path);
    }

    gtk_widget_destroy(dialog);
}

static void stop_cli() {
    // 停止播放进程
    if (play_pgid > 0) {
        killpg(play_pgid, SIGTERM);
        waitpid(-play_pgid, NULL, WNOHANG);
        play_pid = -1;
        play_pgid = -1;
        gtk_widget_set_sensitive(btn_stop, FALSE);
        gtk_widget_set_sensitive(btn_play, TRUE);
        set_error("Playback stopped");
    } else {
        set_error("No active playback");
    }

    // 关闭并重置进度管道
    if (progress_pipe[0] != -1) {
        close(progress_pipe[0]);
        progress_pipe[0] = -1;
    }
    if (progress_pipe[1] != -1) {
        close(progress_pipe[1]);
        progress_pipe[1] = -1;
    }
    set_download_progress(-1);  // 隐藏进度条
}

static pid_t exec_process(const char* cmd) {
    pid_t pid = fork();
    if (pid == 0) {
        execl("/bin/sh", "sh", "-c", cmd, NULL);
        exit(1);
    }
    return pid;
}

// 解析管道中的下载进度数据
static gboolean on_progress_pipe_read(GIOChannel* channel, GIOCondition cond, gpointer data) {
    if (cond & (G_IO_ERR | G_IO_HUP)) {
        // 管道出错或关闭：重置
        g_io_channel_unref(channel);
        return FALSE;
    }

    char buf[64];
    gsize bytes_read;
    GError* err = NULL;

    // 非阻塞读取管道数据
    GIOStatus status = g_io_channel_read_chars(channel, buf, sizeof(buf)-1, &bytes_read, &err);
    if (err != NULL) {
        g_error_free(err);
        return TRUE;
    }
    if (status != G_IO_STATUS_NORMAL || bytes_read == 0) {
        return TRUE;
    }

    buf[bytes_read] = '\0';
    char* progress_str = strstr(buf, "PROGRESS:");
    if (progress_str) {
        progress_str += 9;  // 跳过"PROGRESS:"前缀
        int progress = atoi(progress_str);
        // 在GTK主线程更新UI
        g_idle_add((GSourceFunc)set_download_progress, GINT_TO_POINTER(progress));
    }

    return TRUE;
}

static void run_cli(GtkWidget* widget, gpointer data) {
    if (play_pgid > 0) stop_cli();

    const char* file_path = gtk_entry_get_text(GTK_ENTRY(entry_file));
    const char* url = gtk_entry_get_text(GTK_ENTRY(entry_url));
    const char* geometry = gtk_entry_get_text(GTK_ENTRY(entry_geo));
    gboolean keep_cache = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(chk_keep_cache));

    if ((strlen(file_path) == 0 && strlen(url) == 0) || (strlen(file_path) > 0 && strlen(url) > 0)) {
        set_error("Select local file OR URL (not both)");
        return;
    }

    // 创建进度通信管道
    if (pipe(progress_pipe) == -1) {
        set_error("Failed to create progress pipe");
        return;
    }
    set_pipe_nonblock(progress_pipe[0]);

    // 构建命令
    char cmd[4096] = "./peruere ";
    size_t len = strlen(cmd);

    if (strlen(file_path) > 0) {
        snprintf(cmd + len, sizeof(cmd) - len, "--file \"%s\" ", file_path);
        len = strlen(cmd);
    }
    if (strlen(url) > 0) {
        snprintf(cmd + len, sizeof(cmd) - len, "--url \"%s\" ", url);
        len = strlen(cmd);
    }
    snprintf(cmd + len, sizeof(cmd) - len, "--geometry %s ", geometry);
    len = strlen(cmd);
    if (keep_cache) {
        strncat(cmd, "--keep", sizeof(cmd) - len - 1);
    }

    // 启动子进程，重定向stdout到管道
    play_pid = fork();
    if (play_pid == 0) {
        close(progress_pipe[0]);  // 关闭子进程的读端
        dup2(progress_pipe[1], STDOUT_FILENO);  // stdout -> 管道
        dup2(progress_pipe[1], STDERR_FILENO);  // stderr也重定向
        setpgid(0, 0);
        execl("/bin/sh", "sh", "-c", cmd, NULL);
        exit(1);
    } else if (play_pid > 0) {
        close(progress_pipe[1]);  // 关闭父进程的写端
        play_pgid = play_pid;
        gtk_widget_set_sensitive(btn_play, FALSE);
        gtk_widget_set_sensitive(btn_stop, TRUE);
        set_error("Downloading...");
        set_download_progress(0);  // 初始化进度为0

        // 监测管道可读事件（非阻塞）
        GIOChannel* channel = g_io_channel_unix_new(progress_pipe[0]);
        g_io_channel_set_encoding(channel, NULL, NULL);
        g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP, on_progress_pipe_read, NULL);
        g_io_channel_unref(channel);  // 交给GObject管理生命周期
    } else {
        set_error("Failed to start playback");
        close(progress_pipe[0]);
        close(progress_pipe[1]);
        progress_pipe[0] = progress_pipe[1] = -1;
    }
}

static void clean_cache(GtkWidget* widget, gpointer data) {
    if (play_pgid > 0) stop_cli();
    pid_t pid = exec_process("./peruere --clean-cache");
    if (pid > 0) {
        waitpid(pid, NULL, WNOHANG);
        set_error("Cache cleaned");
    } else {
        set_error("Failed to clean cache");
    }
}

// -------------------------- 帮助窗口相关 --------------------------
static gboolean on_help_key_press(GtkWidget* w, GdkEventKey* ev, gpointer d) {
    if (ev->keyval == GDK_KEY_Escape) {
        gtk_widget_destroy(w);
        return TRUE;
    }
    return FALSE;
}

static void on_help_destroy(GtkWidget* w, gpointer d) {
    help_window = NULL;
}

static void show_help(GtkWidget* widget, gpointer data) {
    if (help_window) {
        gtk_window_present(GTK_WINDOW(help_window));
        return;
    }

    help_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(help_window), "Help");
    gtk_widget_set_size_request(help_window, 500, 300);
    gtk_window_set_transient_for(GTK_WINDOW(help_window), GTK_WINDOW(main_window));
    gtk_window_set_modal(GTK_WINDOW(help_window), TRUE);

    GtkWidget* text_view = gtk_text_view_new();
    GtkTextBuffer* buffer = gtk_text_buffer_new(NULL);
    gtk_text_buffer_set_text(buffer, help_text, -1);
    gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view), buffer);
    gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), FALSE);

    GtkWidget* scrolled_win = gtk_scrolled_window_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(scrolled_win), text_view);
    gtk_container_add(GTK_CONTAINER(help_window), scrolled_win);

    g_signal_connect(help_window, "key-press-event", G_CALLBACK(on_help_key_press), NULL);
    g_signal_connect(help_window, "destroy", G_CALLBACK(on_help_destroy), NULL);

    gtk_widget_show_all(help_window);
}

// -------------------------- 快捷键处理（确保聚焦时才响应） --------------------------
static gboolean on_key_press(GtkWidget* widget, GdkEventKey* event, gpointer data) {
    // 只有输入框有焦点时才处理快捷键
    if (!gtk_widget_has_focus(widget)) return FALSE;
    if (!(event->state & GDK_CONTROL_MASK)) return FALSE;

    InputHistory* hist = data;
    switch (event->keyval) {
        case GDK_KEY_c:  // Ctrl+C 复制
            gtk_editable_copy_clipboard(GTK_EDITABLE(widget));
            return TRUE;
        case GDK_KEY_v:  // Ctrl+V 粘贴
            gtk_editable_paste_clipboard(GTK_EDITABLE(widget));
            input_history_save(hist, gtk_entry_get_text(GTK_ENTRY(widget)));
            return TRUE;
        case GDK_KEY_x:  // Ctrl+X 剪切
            gtk_editable_cut_clipboard(GTK_EDITABLE(widget));
            input_history_save(hist, gtk_entry_get_text(GTK_ENTRY(widget)));
            return TRUE;
        case GDK_KEY_a:  // Ctrl+A 全选
            gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
            return TRUE;
        case GDK_KEY_z:  // Ctrl+Z 撤销
            input_history_undo(hist, widget);
            return TRUE;
        default:
            return FALSE;
    }
}

static void on_entry_changed(GtkWidget* widget, gpointer data) {
    InputHistory* hist = data;
    const char* text = gtk_entry_get_text(GTK_ENTRY(widget));
    if (hist->count == 0 || strcmp(text, hist->history[hist->count-1]) != 0) {
        input_history_save(hist, text);
    }
}

// -------------------------- 托盘功能（修复activate信号错误） --------------------------
static void on_show_window(GtkWidget* widget, gpointer data) {
    gtk_widget_show_all(main_window);
    gtk_window_present(GTK_WINDOW(main_window));
}

static void on_hide_window(GtkWidget* widget, gpointer data) {
    gtk_widget_hide(main_window);
}

static void on_quit_program(GtkWidget* widget, gpointer data) {
    stop_cli();
    // 释放历史记录内存
    for (int i = 0; i < hist_file.count; i++) free(hist_file.history[i]);
    for (int i = 0; i < hist_url.count; i++) free(hist_url.history[i]);
    for (int i = 0; i < hist_geo.count; i++) free(hist_geo.history[i]);
    g_object_unref(tray_indicator);
    if (help_window) gtk_widget_destroy(help_window);
    gtk_widget_destroy(main_window);
    gtk_main_quit();
}

static void on_stop_clicked(GtkWidget* w, gpointer d) {
    stop_cli();
}

// 修复托盘activate信号：用菜单回调替代直接绑定
static void init_tray() {
    tray_indicator = app_indicator_new(
        "video-desktop-player",
        "system-run",
        APP_INDICATOR_CATEGORY_APPLICATION_STATUS
    );
    app_indicator_set_status(tray_indicator, APP_INDICATOR_STATUS_ACTIVE);

    GtkWidget* menu = gtk_menu_new();

    // 显示窗口菜单项
    GtkWidget* show_item = gtk_menu_item_new_with_label("Show Window");
    g_signal_connect(show_item, "activate", G_CALLBACK(on_show_window), NULL);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), show_item);

    // 隐藏窗口菜单项
    GtkWidget* hide_item = gtk_menu_item_new_with_label("Hide Window");
    g_signal_connect(hide_item, "activate", G_CALLBACK(on_hide_window), NULL);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), hide_item);

    // 退出菜单项
    GtkWidget* quit_item = gtk_menu_item_new_with_label("Quit");
    g_signal_connect(quit_item, "activate", G_CALLBACK(on_quit_program), NULL);
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item);

    gtk_widget_show_all(menu);
    app_indicator_set_menu(tray_indicator, GTK_MENU(menu));

    // 移除错误的activate信号绑定（Ayatana不支持直接绑定该信号）
}

// -------------------------- UI初始化（新增进度条组件） --------------------------
static void init_gui() {
    memset(&cfg, 0, sizeof(Config));
    strcpy(cfg.geometry, "1920x1080+0+0");
    cfg.keep_cache = false;

    input_history_init(&hist_file);
    input_history_init(&hist_url);
    input_history_init(&hist_geo);
    input_history_save(&hist_url, "");
    input_history_save(&hist_file, "");
    input_history_save(&hist_geo, cfg.geometry);

    // 主窗口
    main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(main_window), "Video Desktop Player");
    gtk_widget_set_size_request(main_window, 600, 450);  // 增加高度容纳进度条
    gtk_window_set_resizable(GTK_WINDOW(main_window), FALSE);

    // 主垂直布局
    GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
    gtk_container_set_border_width(GTK_CONTAINER(vbox), 20);
    gtk_container_add(GTK_CONTAINER(main_window), vbox);

    // 标题
    GtkWidget* title = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(title), "<span font='24' color='#444'>Video Desktop Player</span>");
    gtk_box_pack_start(GTK_BOX(vbox), title, FALSE, FALSE, 0);
    gtk_widget_set_halign(title, GTK_ALIGN_CENTER);

    // 本地文件行
    GtkWidget* hbox_file = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
    gtk_box_pack_start(GTK_BOX(vbox), hbox_file, FALSE, FALSE, 0);
    GtkWidget* lbl_file = gtk_label_new("Local File:");
    gtk_box_pack_start(GTK_BOX(hbox_file), lbl_file, FALSE, FALSE, 0);
    entry_file = gtk_entry_new();
    gtk_entry_set_max_length(GTK_ENTRY(entry_file), 1023);
    gtk_widget_set_size_request(entry_file, 400, 30);
    gtk_box_pack_start(GTK_BOX(hbox_file), entry_file, TRUE, TRUE, 0);
    btn_browse = gtk_button_new_with_label("Browse...");
    gtk_widget_set_size_request(btn_browse, 80, 30);
    gtk_box_pack_start(GTK_BOX(hbox_file), btn_browse, FALSE, FALSE, 0);

    // URL行
    GtkWidget* hbox_url = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
    gtk_box_pack_start(GTK_BOX(vbox), hbox_url, FALSE, FALSE, 0);
    GtkWidget* lbl_url = gtk_label_new("URL:");
    gtk_box_pack_start(GTK_BOX(hbox_url), lbl_url, FALSE, FALSE, 0);
    entry_url = gtk_entry_new();
    gtk_entry_set_max_length(GTK_ENTRY(entry_url), 1023);
    gtk_widget_set_size_request(entry_url, 480, 30);
    gtk_box_pack_start(GTK_BOX(hbox_url), entry_url, TRUE, TRUE, 0);

    // 窗口几何行
    GtkWidget* hbox_geo = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
    gtk_box_pack_start(GTK_BOX(vbox), hbox_geo, FALSE, FALSE, 0);
    GtkWidget* lbl_geo = gtk_label_new("Window Geometry:");
    gtk_box_pack_start(GTK_BOX(hbox_geo), lbl_geo, FALSE, FALSE, 0);
    entry_geo = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry_geo), cfg.geometry);
    gtk_entry_set_max_length(GTK_ENTRY(entry_geo), 31);
    gtk_widget_set_size_request(entry_geo, 200, 30);
    gtk_box_pack_start(GTK_BOX(hbox_geo), entry_geo, FALSE, FALSE, 0);

    // Keep Cache复选框
    chk_keep_cache = gtk_check_button_new_with_label("Keep Cache (-k)");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_keep_cache), cfg.keep_cache);
    gtk_box_pack_start(GTK_BOX(vbox), chk_keep_cache, FALSE, FALSE, 0);
    gtk_widget_set_margin_start(chk_keep_cache, 10);

    // 按钮行
    GtkWidget* hbox_buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
    gtk_box_pack_start(GTK_BOX(vbox), hbox_buttons, FALSE, FALSE, 0);
    gtk_widget_set_halign(hbox_buttons, GTK_ALIGN_CENTER);
    btn_play = gtk_button_new_with_label("Play");
    gtk_widget_set_size_request(btn_play, 120, 40);
    gtk_box_pack_start(GTK_BOX(hbox_buttons), btn_play, FALSE, FALSE, 0);
    btn_stop = gtk_button_new_with_label("Stop");
    gtk_widget_set_size_request(btn_stop, 120, 40);
    gtk_widget_set_sensitive(btn_stop, FALSE);
    gtk_box_pack_start(GTK_BOX(hbox_buttons), btn_stop, FALSE, FALSE, 0);
    btn_clean = gtk_button_new_with_label("Clean Cache");
    gtk_widget_set_size_request(btn_clean, 120, 40);
    gtk_box_pack_start(GTK_BOX(hbox_buttons), btn_clean, FALSE, FALSE, 0);
    btn_help = gtk_button_new_with_label("Help");
    gtk_widget_set_size_request(btn_help, 120, 40);
    gtk_box_pack_start(GTK_BOX(hbox_buttons), btn_help, FALSE, FALSE, 0);

    // 下载进度区域（新增）
    GtkWidget* hbox_progress = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox_progress, FALSE, FALSE, 0);
    lbl_progress = gtk_label_new("");
    gtk_widget_set_halign(lbl_progress, GTK_ALIGN_CENTER);
    gtk_box_pack_start(GTK_BOX(hbox_progress), lbl_progress, FALSE, FALSE, 0);
    progress_bar = gtk_progress_bar_new();
    gtk_widget_set_size_request(progress_bar, 500, 15);
    gtk_widget_set_halign(progress_bar, GTK_ALIGN_CENTER);
    gtk_box_pack_start(GTK_BOX(hbox_progress), progress_bar, FALSE, FALSE, 0);
    // 初始隐藏进度组件
    gtk_widget_hide(lbl_progress);
    gtk_widget_hide(progress_bar);

    // 错误提示标签
    lbl_error = gtk_label_new(NULL);
    gtk_label_set_markup(GTK_LABEL(lbl_error), "<span color='red'></span>");
    gtk_box_pack_start(GTK_BOX(vbox), lbl_error, FALSE, FALSE, 0);
    gtk_widget_set_halign(lbl_error, GTK_ALIGN_CENTER);
    gtk_widget_hide(lbl_error);

    // 绑定事件
    g_signal_connect(btn_browse, "clicked", G_CALLBACK(open_file_dialog), NULL);
    g_signal_connect(btn_play, "clicked", G_CALLBACK(run_cli), NULL);
    g_signal_connect(btn_stop, "clicked", G_CALLBACK(on_stop_clicked), NULL);
    g_signal_connect(btn_clean, "clicked", G_CALLBACK(clean_cache), NULL);
    g_signal_connect(btn_help, "clicked", G_CALLBACK(show_help), NULL);

    // 输入框快捷键和变化事件（确保聚焦时响应）
    g_signal_connect(entry_file, "key-press-event", G_CALLBACK(on_key_press), &hist_file);
    g_signal_connect(entry_file, "changed", G_CALLBACK(on_entry_changed), &hist_file);
    g_signal_connect(entry_url, "key-press-event", G_CALLBACK(on_key_press), &hist_url);
    g_signal_connect(entry_url, "changed", G_CALLBACK(on_entry_changed), &hist_url);
    g_signal_connect(entry_geo, "key-press-event", G_CALLBACK(on_key_press), &hist_geo);
    g_signal_connect(entry_geo, "changed", G_CALLBACK(on_entry_changed), &hist_geo);

    // 窗口关闭按钮 → 隐藏到托盘
    g_signal_connect(main_window, "delete-event", G_CALLBACK(on_hide_window), NULL);
}

// -------------------------- 主函数 --------------------------
int main(int argc, char* argv[]) {
    gtk_init(&argc, &argv);
    init_gui();
    init_tray();
    gtk_widget_show_all(main_window);
    gtk_main();
    return 0;
}
